"""
可视化工具模块
包含K线图、指标仪表盘、筹码峰等可视化函数
"""

import streamlit as st
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from datetime import datetime
import pandas as pd
import numpy as np
import logging
import traceback

# 配置日志
logger = logging.getLogger(__name__)


def create_candlestick_chart(df, stock_name):
    """创建K线图和技术指标图表（带错误处理）"""
    try:
        fig = make_subplots(
            rows=4, cols=1,
            shared_xaxes=True,
            vertical_spacing=0.03,
            subplot_titles=(
                f'{stock_name} K线图 (含MA5/10/20)', 
                'MACD指标', 
                'KDJ指标', 
                '成交量'
            ),
            row_heights=[0.5, 0.15, 0.15, 0.2]
        )
        
        # K线图
        fig.add_trace(
            go.Candlestick(
                x=df['日期'],
                open=df['开盘'],
                high=df['最高'],
                low=df['最低'],
                close=df['收盘'],
                name='K线',
                increasing_line_color='#ef5350',
                decreasing_line_color='#26a69a'
            ),
            row=1, col=1
        )
        
        # 添加均线（仅显示MA5、MA10、MA20）
        # 优化：增加线宽，使用更醒目的颜色，确保清晰可见
        ma_configs = [
            {'period': 5, 'color': '#FF5252', 'width': 2.0, 'name': 'MA5'},      # 鲜红色，加粗
            {'period': 10, 'color': '#00BCD4', 'width': 2.0, 'name': 'MA10'},    # 亮青色，加粗
            {'period': 20, 'color': '#FFC107', 'width': 2.5, 'name': 'MA20'},    # 琥珀金色，最粗
        ]
        
        for config in ma_configs:
            ma_col = f'MA{config["period"]}'
            if ma_col in df.columns:
                # 过滤掉NaN值，确保均线连续
                ma_data = df[['日期', ma_col]].dropna()
                if len(ma_data) > 0:
                    fig.add_trace(
                        go.Scatter(
                            x=ma_data['日期'],
                            y=ma_data[ma_col],
                            name=config['name'],
                            line=dict(
                                color=config['color'], 
                                width=config['width']
                                # 移除样条平滑，使用精确的线性连接
                                # 金融图表必须准确反映真实数据，不应该平滑
                            ),
                            mode='lines',
                            connectgaps=False,  # 不连接间隙
                            hovertemplate='%{y:.2f}<extra></extra>'
                        ),
                        row=1, col=1
                    )
        
        # 注：布林带、MA60、MA120等其他指标不在K线图显示
        # 保持K线图简洁清晰，仅显示蜡烛图+MA5/10/20
        # 其他技术指标在技术指标仪表盘中查看
        
        # MACD（优化版：过滤NaN值，使用更清晰的颜色）
        if all(col in df.columns for col in ['MACD', 'DIF', 'DEA']):
            macd_data = df[['日期', 'MACD', 'DIF', 'DEA']].dropna()
            if len(macd_data) > 0:
                # MACD柱状图（红绿柱）
                colors_macd = ['#EF5350' if val >= 0 else '#26A69A' for val in macd_data['MACD']]
                fig.add_trace(
                    go.Bar(
                        x=macd_data['日期'], 
                        y=macd_data['MACD'], 
                        name='MACD',
                        marker_color=colors_macd,
                        marker_line_width=0,
                        opacity=0.7
                    ),
                    row=2, col=1
                )
                # DIF线（快线）
                fig.add_trace(
                    go.Scatter(
                        x=macd_data['日期'], 
                        y=macd_data['DIF'], 
                        name='DIF',
                        line=dict(color='#2196F3', width=1.5),
                        mode='lines'
                    ),
                    row=2, col=1
                )
                # DEA线（慢线/信号线）
                fig.add_trace(
                    go.Scatter(
                        x=macd_data['日期'], 
                        y=macd_data['DEA'], 
                        name='DEA',
                        line=dict(color='#FF9800', width=1.5),
                        mode='lines'
                    ),
                    row=2, col=1
                )
                # 添加零轴参考线
                fig.add_hline(y=0, line_dash="dash", line_color="gray", opacity=0.5, row=2, col=1)
        
        # KDJ（优化版：过滤NaN值，添加超买超卖区域）
        if all(col in df.columns for col in ['K', 'D', 'J']):
            kdj_data = df[['日期', 'K', 'D', 'J']].dropna()
            if len(kdj_data) > 0:
                # K线
                fig.add_trace(
                    go.Scatter(
                        x=kdj_data['日期'], 
                        y=kdj_data['K'], 
                        name='K',
                        line=dict(color='#2196F3', width=1.5),
                        mode='lines'
                    ),
                    row=3, col=1
                )
                # D线
                fig.add_trace(
                    go.Scatter(
                        x=kdj_data['日期'], 
                        y=kdj_data['D'], 
                        name='D',
                        line=dict(color='#FF9800', width=1.5),
                        mode='lines'
                    ),
                    row=3, col=1
                )
                # J线
                fig.add_trace(
                    go.Scatter(
                        x=kdj_data['日期'], 
                        y=kdj_data['J'], 
                        name='J',
                        line=dict(color='#9C27B0', width=1.5),
                        mode='lines'
                    ),
                    row=3, col=1
                )
                
                # 添加超买超卖参考线
                fig.add_hline(y=80, line_dash="dash", line_color="#EF5350", opacity=0.5, row=3, col=1, 
                             annotation_text="超买", annotation_position="right")
                fig.add_hline(y=20, line_dash="dash", line_color="#26A69A", opacity=0.5, row=3, col=1,
                             annotation_text="超卖", annotation_position="right")
                fig.add_hline(y=50, line_dash="dot", line_color="gray", opacity=0.3, row=3, col=1)
        
        # 成交量（优化版：与K线颜色匹配）
        colors_vol = ['#EF5350' if df['收盘'].iloc[i] >= df['开盘'].iloc[i] else '#26A69A' 
                      for i in range(len(df))]
        fig.add_trace(
            go.Bar(
                x=df['日期'], 
                y=df['成交量'], 
                name='成交量',
                marker_color=colors_vol,
                marker_line_width=0,
                opacity=0.6
            ),
            row=4, col=1
        )
        
        # 成交量均线
        vol_ma_configs = [
            {'col': 'VOL_MA5', 'name': 'VOL_MA5', 'color': '#FFA726', 'width': 1.5},
            {'col': 'VOL_MA10', 'name': 'VOL_MA10', 'color': '#66BB6A', 'width': 1.5},
        ]
        
        for config in vol_ma_configs:
            if config['col'] in df.columns:
                vol_ma_data = df[['日期', config['col']]].dropna()
                if len(vol_ma_data) > 0:
                    fig.add_trace(
                        go.Scatter(
                            x=vol_ma_data['日期'], 
                            y=vol_ma_data[config['col']], 
                            name=config['name'],
                            line=dict(color=config['color'], width=config['width']),
                            mode='lines'
                        ),
                        row=4, col=1
                    )
    
        # 优化布局
        fig.update_layout(
            height=1200,
            showlegend=True,
            xaxis_rangeslider_visible=False,
            hovermode='x unified',
            template='plotly_white',
            legend=dict(
                orientation="h",
                yanchor="bottom",
                y=1.02,
                xanchor="right",
                x=1,
                bgcolor="rgba(255, 255, 255, 0.8)",
                bordercolor="LightGray",
                borderwidth=1,
                tracegroupgap=30  # 增加图例组之间的间距
            ),
            font=dict(size=12),
            title_font_size=14
        )
        
        # 优化图例显示策略：
        # 1. K线图区域：显示 K线 + MA5/10/20（最重要，始终显示）
        # 2. 其他指标：在各自子图中通过标注显示，不在顶部图例中显示
        # 这样可以保持图例简洁，避免信息过载
        for trace in fig.data:
            if trace.name in ['K线', 'MA5', 'MA10', 'MA20']:
                # K线和均线：始终在图例中显示
                trace.legendgroup = 'K线图'
                trace.showlegend = True
            else:
                # MACD、KDJ、成交量：隐藏图例，通过子图标题识别
                # 这样顶部图例只显示K线+MA5/10/20，更清晰
                trace.showlegend = False
        
        # 优化坐标轴显示
        fig.update_xaxes(
            showgrid=True, 
            gridwidth=0.5, 
            gridcolor='rgba(128,128,128,0.2)',
            showline=True,
            linewidth=1,
            linecolor='LightGray'
        )
        fig.update_yaxes(
            showgrid=True, 
            gridwidth=0.5, 
            gridcolor='rgba(128,128,128,0.2)',
            showline=True,
            linewidth=1,
            linecolor='LightGray'
        )
        
        # 为不同子图设置标题
        fig.update_yaxes(title_text="价格", row=1, col=1)
        fig.update_yaxes(title_text="MACD", row=2, col=1)
        fig.update_yaxes(title_text="KDJ", row=3, col=1)
        fig.update_yaxes(title_text="成交量", row=4, col=1)
        
        return fig
    
    except Exception as e:
        logger.error(f"创建K线图时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 创建K线图时出现错误: {str(e)}")
        return None


def create_indicator_dashboard(df):
    """创建技术指标仪表盘（增强版，带错误处理）"""
    if df is None or len(df) == 0:
        return
    
    try:
        latest = df.iloc[-1]
        
        # 第一行：主要动量指标
        st.markdown("### 📊 动量指标")
        col1, col2, col3, col4, col5 = st.columns(5)
        
        with col1:
            if 'RSI6' in latest and pd.notna(latest['RSI6']):
                rsi_color = "🔴" if latest['RSI6'] > 70 else "🟢" if latest['RSI6'] < 30 else "🟡"
                st.metric("RSI(6)", f"{latest['RSI6']:.2f}", 
                         delta=f"{rsi_color} {'超买' if latest['RSI6'] > 70 else '超卖' if latest['RSI6'] < 30 else '正常'}")
        
        with col2:
            if 'K' in latest and 'D' in latest and pd.notna(latest['K']):
                kdj_signal = "金叉 ⬆️" if latest['K'] > latest['D'] else "死叉 ⬇️"
                st.metric("KDJ", kdj_signal, 
                         delta=f"K:{latest['K']:.2f}")
        
        with col3:
            if 'DIF' in latest and 'DEA' in latest and pd.notna(latest['DIF']):
                macd_signal = "金叉 ⬆️" if latest['DIF'] > latest['DEA'] else "死叉 ⬇️"
                st.metric("MACD", macd_signal,
                         delta=f"{latest['MACD']:.2f}")
        
        with col4:
            if 'CCI' in latest and pd.notna(latest['CCI']):
                cci_status = "超买" if latest['CCI'] > 100 else "超卖" if latest['CCI'] < -100 else "正常"
                st.metric("CCI", f"{latest['CCI']:.2f}",
                         delta=cci_status)
        
        with col5:
            if 'WR14' in latest and pd.notna(latest['WR14']):
                wr_status = "超买" if latest['WR14'] > -20 else "超卖" if latest['WR14'] < -80 else "正常"
                st.metric("WR(14)", f"{latest['WR14']:.2f}",
                         delta=wr_status)
        
        # 第二行：趋势指标
        st.markdown("### 📈 趋势指标")
        col1, col2, col3, col4, col5 = st.columns(5)
        
        with col1:
            if 'BOLL_UPPER' in latest and pd.notna(latest['BOLL_UPPER']):
                close_price = latest['收盘']
                boll_pos = "上轨 ⬆️" if close_price >= latest['BOLL_UPPER'] else \
                           "下轨 ⬇️" if close_price <= latest['BOLL_LOWER'] else "中轨 ➡️"
                st.metric("布林带", boll_pos,
                         delta=f"带宽:{(latest['BOLL_UPPER']-latest['BOLL_LOWER']):.2f}")
        
        with col2:
            if 'ADX' in latest and pd.notna(latest['ADX']):
                adx_strength = "强趋势" if latest['ADX'] > 25 else "弱趋势" if latest['ADX'] > 20 else "无趋势"
                st.metric("ADX", f"{latest['ADX']:.2f}",
                         delta=adx_strength)
        
        with col3:
            if 'PDI' in latest and 'MDI' in latest and pd.notna(latest['PDI']):
                dmi_signal = "上涨 ⬆️" if latest['PDI'] > latest['MDI'] else "下跌 ⬇️"
                st.metric("DMI", dmi_signal,
                         delta=f"+DI:{latest['PDI']:.1f}")
        
        with col4:
            if 'BIAS6' in latest and pd.notna(latest['BIAS6']):
                bias_status = "超买" if latest['BIAS6'] > 10 else "超卖" if latest['BIAS6'] < -10 else "正常"
                st.metric("BIAS(6)", f"{latest['BIAS6']:.2f}%",
                         delta=bias_status)
        
        with col5:
            if 'ROC' in latest and pd.notna(latest['ROC']):
                roc_status = "强势" if latest['ROC'] > 5 else "弱势" if latest['ROC'] < -5 else "平稳"
                st.metric("ROC", f"{latest['ROC']:.2f}%",
                         delta=roc_status)
        
        # 第三行：成交量和心理指标
        st.markdown("### 📉 成交量与心理指标")
        col1, col2, col3, col4 = st.columns(4)
        
        with col1:
            if 'OBV' in latest and pd.notna(latest['OBV']):
                obv_val = latest['OBV']
                obv_display = f"{obv_val/100000000:.2f}亿" if obv_val > 100000000 else f"{obv_val/10000:.2f}万"
                st.metric("OBV能量潮", obv_display)
        
        with col2:
            if 'ATR' in latest and pd.notna(latest['ATR']):
                st.metric("ATR波动", f"{latest['ATR']:.2f}",
                         delta="真实波幅")
        
        with col3:
            if 'PSY' in latest and pd.notna(latest['PSY']):
                psy_status = "乐观" if latest['PSY'] > 75 else "悲观" if latest['PSY'] < 25 else "中性"
                st.metric("PSY心理线", f"{latest['PSY']:.2f}",
                         delta=psy_status)
        
        with col4:
            # 显示MA20位置
            if 'MA20' in latest and pd.notna(latest['MA20']):
                ma_diff = (latest['收盘'] - latest['MA20']) / latest['MA20'] * 100
                ma_status = "站上" if ma_diff > 0 else "跌破"
                st.metric("MA20偏离", f"{ma_diff:+.2f}%",
                         delta=f"{ma_status}均线")
    
    except Exception as e:
        logger.error(f"创建技术指标仪表盘时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示技术指标时出现错误，详细信息已记录到日志")


def display_realtime_info(realtime_data):
    """显示实时行情（带完善的错误处理）"""
    if realtime_data is None:
        st.error("无法获取实时数据")
        return
    
    try:
        col1, col2 = st.columns([3, 1])
        with col1:
            st.title(f"{realtime_data.get('股票名称', 'N/A')} ({realtime_data.get('股票代码', 'N/A')})")
        with col2:
            st.metric("更新时间", datetime.now().strftime("%H:%M:%S"))
        
        col1, col2, col3, col4, col5, col6 = st.columns(6)
        
        # 安全获取数值
        def safe_get(key, default=0):
            value = realtime_data.get(key)
            return value if value is not None else default
        
        with col1:
            try:
                st.metric(
                    "最新价",
                    f"¥{safe_get('最新价'):.2f}",
                    delta=f"{safe_get('涨跌幅'):.2f}%",
                    delta_color="normal"
                )
            except Exception as e:
                logger.error(f"显示最新价时出错: {e}\n{traceback.format_exc()}")
                st.metric("最新价", "N/A")
        
        with col2:
            try:
                st.metric("涨跌额", f"¥{safe_get('涨跌额'):.2f}")
            except Exception as e:
                logger.error(f"显示涨跌额时出错: {e}\n{traceback.format_exc()}")
                st.metric("涨跌额", "N/A")
        
        with col3:
            try:
                st.metric("换手率", f"{safe_get('换手率'):.2f}%")
            except Exception as e:
                logger.error(f"显示换手率时出错: {e}\n{traceback.format_exc()}")
                st.metric("换手率", "N/A")
        
        with col4:
            try:
                st.metric("量比", f"{safe_get('量比'):.2f}")
            except Exception as e:
                logger.error(f"显示量比时出错: {e}\n{traceback.format_exc()}")
                st.metric("量比", "N/A")
        
        with col5:
            try:
                volume = safe_get('成交量')
                st.metric("成交量", f"{volume/10000:.2f}万手" if volume else "N/A")
            except Exception as e:
                logger.error(f"显示成交量时出错: {e}\n{traceback.format_exc()}")
                st.metric("成交量", "N/A")
        
        with col6:
            try:
                amount = safe_get('成交额')
                st.metric("成交额", f"{amount/100000000:.2f}亿" if amount else "N/A")
            except Exception as e:
                logger.error(f"显示成交额时出错: {e}\n{traceback.format_exc()}")
                st.metric("成交额", "N/A")
        
        st.subheader("📊 详细行情")
        col1, col2, col3, col4 = st.columns(4)
        
        with col1:
            try:
                st.write("**开盘价:**", f"¥{safe_get('开盘价'):.2f}")
                st.write("**最高价:**", f"¥{safe_get('最高价'):.2f}")
            except Exception as e:
                logger.error(f"显示开盘/最高价时出错: {e}\n{traceback.format_exc()}")
                st.write("**开盘价:**", "N/A")
                st.write("**最高价:**", "N/A")
        
        with col2:
            try:
                st.write("**最低价:**", f"¥{safe_get('最低价'):.2f}")
                st.write("**昨收:**", f"¥{safe_get('昨收'):.2f}")
            except Exception as e:
                logger.error(f"显示最低价/昨收时出错: {e}\n{traceback.format_exc()}")
                st.write("**最低价:**", "N/A")
                st.write("**昨收:**", "N/A")
        
        with col3:
            try:
                pe = safe_get('市盈率')
                pb = safe_get('市净率')
                st.write("**市盈率:**", f"{pe:.2f}" if pe else "N/A")
                st.write("**市净率:**", f"{pb:.2f}" if pb else "N/A")
            except Exception as e:
                logger.error(f"显示市盈率/市净率时出错: {e}\n{traceback.format_exc()}")
                st.write("**市盈率:**", "N/A")
                st.write("**市净率:**", "N/A")
        
        with col4:
            try:
                total_mv = safe_get('总市值')
                float_mv = safe_get('流通市值')
                st.write("**总市值:**", f"{total_mv/100000000:.2f}亿" if total_mv else "N/A")
                st.write("**流通市值:**", f"{float_mv/100000000:.2f}亿" if float_mv else "N/A")
            except Exception as e:
                logger.error(f"显示市值时出错: {e}\n{traceback.format_exc()}")
                st.write("**总市值:**", "N/A")
                st.write("**流通市值:**", "N/A")
    
    except Exception as e:
        logger.error(f"显示实时信息时发生严重错误: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示实时数据时出现错误，详细信息已记录到日志")
        st.exception(e)  # 在界面显示错误详情


def create_chip_distribution_chart(df, lookback_days=90):
    """创建筹码分布图（横向柱状图，带错误处理）"""
    if len(df) < 20:
        return None
    
    try:
        # 确保 lookback_days 是整数
        lookback_days = int(lookback_days)
        recent_data = df.tail(lookback_days) if len(df) >= lookback_days else df
        
        # 创建价格区间
        price_min = recent_data['最低'].min()
        price_max = recent_data['最高'].max()
        bins = 30
        price_bins = np.linspace(price_min, price_max, bins + 1)
        
        # 计算每个价格区间的成交量
        volume_distribution = []
        price_values = []  # 使用数值而不是字符串
        price_labels = []  # 用于显示的格式化字符串
        
        for i in range(len(price_bins) - 1):
            bin_low = price_bins[i]
            bin_high = price_bins[i + 1]
            
            mask = (recent_data['收盘'] >= bin_low) & (recent_data['收盘'] < bin_high)
            bin_volume = recent_data.loc[mask, '成交量'].sum()
            
            price_mid = (bin_low + bin_high) / 2
            volume_distribution.append(bin_volume)
            price_values.append(price_mid)
            price_labels.append(f"{price_mid:.2f}")
        
        # 创建横向柱状图
        fig = go.Figure()
        
        # 筹码分布柱状图
        fig.add_trace(go.Bar(
            y=price_values,  # 使用数值坐标
            x=volume_distribution,
            orientation='h',
            marker=dict(
                color=volume_distribution,
                colorscale='RdYlGn',
                showscale=True,
                colorbar=dict(title="成交量")
            ),
            name='筹码分布',
            text=price_labels,  # 显示格式化的标签
            hovertemplate='价格: ¥%{y:.2f}<br>成交量: %{x:.0f}<extra></extra>'
        ))
        
        # 添加当前价格线
        current_price = float(df.iloc[-1]['收盘'])
        fig.add_hline(
            y=current_price,  # 使用数值
            line_dash="dash",
            line_color="red",
            line_width=2,
            annotation_text=f"当前价: ¥{current_price:.2f}",
            annotation_position="right"
        )
        
        # 计算并标记主力成本
        total_volume = sum(volume_distribution)
        if total_volume > 0:
            max_volume_idx = volume_distribution.index(max(volume_distribution))
            main_cost = price_values[max_volume_idx]  # 使用数值
            
            fig.add_hline(
                y=main_cost,  # 使用数值
                line_dash="dot",
                line_color="blue",
                line_width=2,
                annotation_text=f"主力成本: ¥{main_cost:.2f}",
                annotation_position="left"
            )
    
        fig.update_layout(
            title=f'筹码分布图（近{lookback_days}日）',
            xaxis_title='成交量',
            yaxis_title='价格区间 (¥)',
            height=600,
            showlegend=False,
            hovermode='closest',
            template='plotly_white'
        )
        
        return fig
    
    except Exception as e:
        logger.error(f"创建筹码分布图时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 创建筹码分布图时出现错误: {str(e)}")
        return None


def display_ma_analysis(ma_analysis):
    """显示均线分析结果（带错误处理）"""
    if not ma_analysis:
        return
    
    try:
        st.subheader("📊 均线系统分析")
        
        # 均线排列
        if '短期排列' in ma_analysis:
            col1, col2 = st.columns(2)
            
            with col1:
                st.markdown("#### 📈 均线排列")
                arrangement_color = "🟢" if ma_analysis.get('短期状态') == 'bullish' else "🔴" if ma_analysis.get('短期状态') == 'bearish' else "🟡"
                st.markdown(f"{arrangement_color} **{ma_analysis['短期排列']}**")
                st.write(ma_analysis.get('短期信号', ''))
                
                if '中期排列' in ma_analysis:
                    st.write(f"中期: {ma_analysis['中期排列']}")
                    st.write(ma_analysis.get('中期信号', ''))
            
            with col2:
                st.markdown("#### 🎯 价格位置")
                st.write(f"**{ma_analysis.get('价格位置', '')}**")
                st.write(ma_analysis.get('价格信号', ''))
    
    except Exception as e:
        logger.error(f"显示均线分析时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示均线分析时出现错误，详细信息已记录到日志")


def display_ma_cross(ma_cross):
    """显示均线金叉死叉分析（带错误处理）"""
    if not ma_cross:
        return
    
    try:
        st.markdown("#### 🔀 金叉死叉")
        
        col1, col2 = st.columns(2)
        
        with col1:
            if 'MA5_MA10_信号' in ma_cross:
                status_icon = "🔥" if 'golden_cross' in str(ma_cross.get('MA5_MA10_状态', '')) else "⚠️" if 'death_cross' in str(ma_cross.get('MA5_MA10_状态', '')) else "📊"
                st.markdown(f"{status_icon} **MA5 vs MA10**")
                st.write(ma_cross['MA5_MA10_信号'])
        
        with col2:
            if 'MA10_MA20_信号' in ma_cross:
                st.markdown("📊 **MA10 vs MA20**")
                st.write(ma_cross['MA10_MA20_信号'])
    
    except Exception as e:
        logger.error(f"显示均线金叉死叉时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示均线金叉死叉时出现错误，详细信息已记录到日志")


def display_ma_support_resistance(support_resistance):
    """显示均线支撑压力（带错误处理）"""
    if not support_resistance:
        return
    
    try:
        st.markdown("#### 🎯 均线支撑压力")
        
        col1, col2, col3 = st.columns(3)
        
        with col1:
            if '最近支撑' in support_resistance:
                st.metric(
                    support_resistance['最近支撑'],
                    support_resistance['支撑价位'],
                    delta=f"距离 {support_resistance['支撑距离']}"
                )
        
        with col2:
            if '最近压力' in support_resistance:
                st.metric(
                    support_resistance['最近压力'],
                    support_resistance['压力价位'],
                    delta=f"距离 {support_resistance['压力距离']}"
                )
        
        with col3:
            if '均线状态' in support_resistance:
                st.metric(
                    "均线状态",
                    support_resistance['均线状态']
                )
                st.caption(support_resistance.get('状态评价', ''))
    
    except Exception as e:
        logger.error(f"显示均线支撑压力时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示均线支撑压力时出现错误，详细信息已记录到日志")


def display_chip_analysis(chip_dist, chip_conc, chip_mig):
    """显示筹码峰分析结果（带错误处理）"""
    try:
        st.subheader("💎 筹码峰分析")
        
        # 第一行：筹码分布基本信息
        st.markdown("#### 📊 筹码分布概况")
        if chip_dist:
            col1, col2, col3, col4 = st.columns(4)
            
            with col1:
                if '筹码平均成本' in chip_dist:
                    st.metric("筹码平均成本", chip_dist['筹码平均成本'])
            
            with col2:
                if '当前价格' in chip_dist:
                    st.metric("当前价格", chip_dist['当前价格'])
            
            with col3:
                if '成本乖离率' in chip_dist:
                    st.metric("成本乖离率", chip_dist['成本乖离率'])
            
            with col4:
                if '获利盘状态' in chip_dist:
                    st.metric("获利盘状态", chip_dist['获利盘状态'])
            
            if '获利盘评价' in chip_dist:
                st.info(chip_dist['获利盘评价'])
        
        st.markdown("---")
        
        # 第二行：筹码集中度
        st.markdown("#### 🎯 筹码集中度")
        if chip_conc:
            col1, col2 = st.columns(2)
            
            with col1:
                if '主力成本区间' in chip_conc:
                    st.write(f"**主力成本区间:** {chip_conc['主力成本区间']}")
                    st.write(f"**主力成本中枢:** {chip_conc['主力成本中枢']}")
                    st.write(f"**主峰集中度:** {chip_conc['主峰集中度']}")
                
                if '集中度评价' in chip_conc:
                    st.success(f"{chip_conc['集中度信号']}")
            
            with col2:
                if '价格距主力成本' in chip_conc:
                    st.write(f"**价格距主力成本:** {chip_conc['价格距主力成本']}")
                    st.write(f"**相对位置:** {chip_conc['相对位置']}")
                
                if '位置评价' in chip_conc:
                    st.info(chip_conc['位置评价'])
                
                if '双峰结构' in chip_conc and chip_conc['双峰结构'] == '是':
                    st.write(f"**次峰位置:** {chip_conc.get('次峰位置', '')}")
                    st.caption(chip_conc.get('次峰评价', ''))
        
        st.markdown("---")
        
        # 第三行：筹码移动
        st.markdown("#### 🔄 筹码移动趋势")
        if chip_mig:
            col1, col2, col3 = st.columns(3)
            
            with col1:
                if '短期筹码成本' in chip_mig:
                    st.metric("短期成本(30日)", chip_mig['短期筹码成本'])
            
            with col2:
                if '长期筹码成本' in chip_mig:
                    st.metric("长期成本(90日)", chip_mig['长期筹码成本'])
            
            with col3:
                if '成本变化' in chip_mig:
                    st.metric("成本变化", chip_mig['成本变化'])
            
            if '筹码移动' in chip_mig:
                movement_color = "success" if "上移" in chip_mig['筹码移动'] else "error" if "下移" in chip_mig['筹码移动'] else "info"
                getattr(st, movement_color)(f"**{chip_mig['筹码移动']}** - {chip_mig.get('移动评价', '')}")
            
            if '近期换手率' in chip_mig:
                st.write(f"**近期平均换手率:** {chip_mig['近期换手率']}")
                st.caption(chip_mig.get('换手评价', ''))
    
    except Exception as e:
        logger.error(f"显示筹码峰分析时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示筹码峰分析时出现错误，详细信息已记录到日志")


def display_analysis_result(signals, score, recommendation, desc, risk_info):
    """显示分析结果（带错误处理）"""
    try:
        st.subheader("🎯 量化分析结果")
        
        col1, col2 = st.columns([1, 2])
        
        with col1:
            fig_gauge = go.Figure(go.Indicator(
                mode="gauge+number+delta",
                value=score,
                domain={'x': [0, 1], 'y': [0, 1]},
                title={'text': "综合评分", 'font': {'size': 24}},
                delta={'reference': 50},
                gauge={
                    'axis': {'range': [None, 100], 'tickwidth': 1, 'tickcolor': "darkblue"},
                    'bar': {'color': "darkblue"},
                    'bgcolor': "white",
                    'borderwidth': 2,
                    'bordercolor': "gray",
                    'steps': [
                        {'range': [0, 30], 'color': '#ffcdd2'},
                        {'range': [30, 45], 'color': '#fff9c4'},
                        {'range': [45, 60], 'color': '#e1f5dd'},
                        {'range': [60, 75], 'color': '#c8e6c9'},
                        {'range': [75, 100], 'color': '#a5d6a7'}
                    ],
                    'threshold': {
                        'line': {'color': "red", 'width': 4},
                        'thickness': 0.75,
                        'value': 75
                    }
                }
            ))
            
            fig_gauge.update_layout(
                height=300,
                margin=dict(l=20, r=20, t=50, b=20)
            )
            st.plotly_chart(fig_gauge, use_container_width=True)
        
        with col2:
            st.markdown(f"### {recommendation[0]}")
            
            if recommendation[2] == "success":
                st.markdown(f'<div style="padding: 20px; border-radius: 10px; background-color: #d4edda; border: 1px solid #c3e6cb; color: #155724;"><h4>✅ {recommendation[1]}</h4></div>', 
                           unsafe_allow_html=True)
            elif recommendation[2] == "warning":
                st.markdown(f'<div style="padding: 20px; border-radius: 10px; background-color: #fff3cd; border: 1px solid #ffeaa7; color: #856404;"><h4>⚠️ {recommendation[1]}</h4></div>', 
                           unsafe_allow_html=True)
            else:
                st.markdown(f'<div style="padding: 20px; border-radius: 10px; background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24;"><h4>❌ {recommendation[1]}</h4></div>', 
                           unsafe_allow_html=True)
            
            if risk_info:
                st.markdown("#### 📉 风险指标")
                risk_col1, risk_col2, risk_col3 = st.columns(3)
                
                with risk_col1:
                    if '波动率' in risk_info:
                        st.metric("波动率", risk_info['波动率'], 
                                 delta=risk_info.get('波动率评价', ''))
                
                with risk_col2:
                    if '最大回撤' in risk_info:
                        st.metric("最大回撤", risk_info['最大回撤'],
                                 delta=risk_info.get('回撤评价', ''))
                
                with risk_col3:
                    if '夏普比率' in risk_info:
                        st.metric("夏普比率", risk_info['夏普比率'],
                                 delta=risk_info.get('夏普评价', ''))
        
        st.markdown("#### 📋 技术信号详情")
        
        if signals:
            positive_signals = [s for s in signals if '✅' in s or '🚀' in s or '💎' in s or '🔥' in s]
            negative_signals = [s for s in signals if '❌' in s or '⚠️' in s]
            
            col1, col2 = st.columns(2)
            
            with col1:
                if positive_signals:
                    st.success("**积极信号:**")
                    for signal in positive_signals:
                        st.write(f"• {signal}")
            
            with col2:
                if negative_signals:
                    st.warning("**风险信号:**")
                    for signal in negative_signals:
                        st.write(f"• {signal}")
        else:
            st.info("暂无技术信号")
    
    except Exception as e:
        logger.error(f"显示分析结果时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示分析结果时出现错误，详细信息已记录到日志")


def display_trading_decision(trading_plan: dict):
    """
    显示交易决策分析
    
    参数:
        trading_plan: 交易计划数据
    """
    try:
        import plotly.graph_objects as go
        from plotly.subplots import make_subplots
        
        st.markdown("---")
        st.header("💰 交易决策分析")
        st.markdown("基于技术指标、价格位置、多周期分析的综合交易建议")
        
        if not trading_plan:
            st.warning("暂无交易决策数据")
            return
        
        # ===== 1. 价格关键位分析 =====
        st.subheader("📍 价格关键位分析")
        price_levels = trading_plan.get('price_levels', {})
        
        if price_levels:
            col1, col2, col3 = st.columns(3)
            
            with col1:
                st.metric("当前价格", f"¥{price_levels.get('current_price', 0):.2f}")
            
            with col2:
                recent_high = price_levels.get('recent_high', 0)
                st.metric("近期高点", f"¥{recent_high:.2f}", 
                         delta=f"{((recent_high / price_levels.get('current_price', 1) - 1) * 100):.2f}%")
            
            with col3:
                recent_low = price_levels.get('recent_low', 0)
                st.metric("近期低点", f"¥{recent_low:.2f}",
                         delta=f"{((recent_low / price_levels.get('current_price', 1) - 1) * 100):.2f}%")
            
            # 支撑位和压力位
            col1, col2 = st.columns(2)
            
            with col1:
                st.markdown("##### 🛡️ 关键支撑位")
                supports = price_levels.get('support_levels', [])
                if supports:
                    for name, price, strength in supports:
                        color = "🟢" if strength == "强" else "🟡"
                        st.write(f"{color} **{name}**: ¥{price:.2f} ({strength}支撑)")
                else:
                    st.info("暂无明确支撑位")
            
            with col2:
                st.markdown("##### ⚠️ 关键压力位")
                resistances = price_levels.get('resistance_levels', [])
                if resistances:
                    for name, price, strength in resistances:
                        color = "🔴" if strength == "强" else "🟠"
                        st.write(f"{color} **{name}**: ¥{price:.2f} ({strength}压力)")
                else:
                    st.info("暂无明确压力位")
            
            # 突破信号
            breakthrough = price_levels.get('breakthrough_signal', {})
            if breakthrough.get('has_breakthrough'):
                st.markdown("##### ⚡ 突破信号")
                signals = breakthrough.get('signals', [])
                for signal in signals:
                    signal_type = signal.get('type')
                    icon = "📈" if '向上' in signal_type else "📉"
                    st.write(f"{icon} **{signal_type}** {signal.get('level')} (¥{signal.get('price', 0):.2f}) - {signal.get('meaning')}")
        
        # ===== 2. 仓位管理建议 =====
        st.markdown("---")
        st.subheader("📊 仓位管理建议")
        position_advice = trading_plan.get('position_advice', {})
        
        if position_advice:
            action = position_advice.get('action', '观望')
            position_change = position_advice.get('position_change', '0%')
            reason = position_advice.get('reason', '')
            risk_level = position_advice.get('risk_level', '未知')
            
            # 使用不同颜色显示不同建议
            if '加仓' in action:
                st.success(f"### 🚀 {action} ({position_change})")
            elif '减仓' in action:
                st.error(f"### 🔻 {action} ({position_change})")
            else:
                st.info(f"### ⏸️ {action} ({position_change})")
            
            st.write(f"**原因**: {reason}")
            st.write(f"**风险等级**: {risk_level}")
            
            # 评分雷达图
            col1, col2 = st.columns([2, 1])
            
            with col1:
                buy_score = position_advice.get('buy_score', 0)
                sell_score = position_advice.get('sell_score', 0)
                total_score = position_advice.get('total_score', 0)
                
                fig = go.Figure()
                
                fig.add_trace(go.Bar(
                    x=['买入信号', '卖出信号'],
                    y=[buy_score, sell_score],
                    marker_color=['#26a69a', '#ef5350'],
                    text=[buy_score, sell_score],
                    textposition='auto',
                ))
                
                fig.update_layout(
                    title='多空信号强度对比',
                    yaxis_title='评分',
                    height=300,
                    showlegend=False
                )
                
                st.plotly_chart(fig, use_container_width=True)
            
            with col2:
                st.markdown("##### 📋 详细指标")
                details = position_advice.get('details', {})
                for key, value in details.items():
                    st.write(f"**{key}**: {value}")
        
        # ===== 3. 买入价格建议 =====
        st.markdown("---")
        st.subheader("💵 合理买入价格")
        entry_price = trading_plan.get('entry_price', {})
        
        if entry_price:
            current = entry_price.get('current_price', 0)
            aggressive = entry_price.get('aggressive_entry')
            moderate = entry_price.get('moderate_entry')
            conservative = entry_price.get('conservative_entry')
            stop_loss = entry_price.get('stop_loss')
            
            col1, col2, col3, col4 = st.columns(4)
            
            if aggressive:
                with col1:
                    st.metric("激进买入", f"¥{aggressive:.2f}",
                             delta=f"{((aggressive / current - 1) * 100):.2f}%")
            
            if moderate:
                with col2:
                    st.metric("稳健买入", f"¥{moderate:.2f}",
                             delta=f"{((moderate / current - 1) * 100):.2f}%")
            
            if conservative:
                with col3:
                    st.metric("保守买入", f"¥{conservative:.2f}",
                             delta=f"{((conservative / current - 1) * 100):.2f}%")
            
            if stop_loss:
                with col4:
                    st.metric("止损价", f"¥{stop_loss:.2f}",
                             delta=f"{((stop_loss / current - 1) * 100):.2f}%",
                             delta_color="inverse")
            
            strategy = entry_price.get('strategy', '')
            if strategy:
                st.info(f"💡 **策略建议**: {strategy}")
        
        # ===== 4. 多周期投资策略 =====
        st.markdown("---")
        st.subheader("⏱️ 多周期投资策略")
        multi_strategy = trading_plan.get('multi_strategy', {})
        
        if multi_strategy:
            recommendations = multi_strategy.get('recommendations', {})
            
            # 综合评分
            overall_score = multi_strategy.get('overall_score', 0)
            overall_rating = multi_strategy.get('overall_rating', '中性')
            
            col1, col2 = st.columns([1, 2])
            
            with col1:
                # 综合评分仪表盘
                fig = go.Figure(go.Indicator(
                    mode = "gauge+number+delta",
                    value = overall_score,
                    domain = {'x': [0, 1], 'y': [0, 1]},
                    title = {'text': "综合评分"},
                    delta = {'reference': 50},
                    gauge = {
                        'axis': {'range': [None, 100]},
                        'bar': {'color': "#4ECDC4"},
                        'steps': [
                            {'range': [0, 40], 'color': "#ef5350"},
                            {'range': [40, 60], 'color': "#ffa726"},
                            {'range': [60, 100], 'color': "#26a69a"}
                        ],
                        'threshold': {
                            'line': {'color': "red", 'width': 4},
                            'thickness': 0.75,
                            'value': 70
                        }
                    }
                ))
                
                fig.update_layout(height=250)
                st.plotly_chart(fig, use_container_width=True)
                
                st.metric("综合评级", overall_rating)
            
            with col2:
                # 三个周期的得分对比
                periods = ['短线', '中线', '长线']
                scores = []
                for period in periods:
                    period_data = recommendations.get(period, {})
                    scores.append(period_data.get('score', 50))
                
                fig = go.Figure()
                
                fig.add_trace(go.Bar(
                    x=periods,
                    y=scores,
                    marker_color=['#FF6B6B', '#4ECDC4', '#45B7D1'],
                    text=scores,
                    textposition='auto',
                ))
                
                fig.add_hline(y=50, line_dash="dash", line_color="gray",
                             annotation_text="中性线", annotation_position="right")
                fig.add_hline(y=60, line_dash="dot", line_color="green",
                             annotation_text="看好", annotation_position="right")
                fig.add_hline(y=70, line_dash="dot", line_color="darkgreen",
                             annotation_text="非常看好", annotation_position="right")
                
                fig.update_layout(
                    title='不同周期评分对比',
                    yaxis_title='评分',
                    height=250,
                    showlegend=False
                )
                
                st.plotly_chart(fig, use_container_width=True)
            
            # 详细策略
            st.markdown("##### 📝 详细策略建议")
            
            tabs = st.tabs(["📈 短线策略", "📊 中线策略", "📉 长线策略"])
            
            for idx, period in enumerate(periods):
                with tabs[idx]:
                    period_data = recommendations.get(period, {})
                    
                    if period_data:
                        col1, col2, col3 = st.columns(3)
                        
                        with col1:
                            score = period_data.get('score', 50)
                            st.metric("评分", score)
                        
                        with col2:
                            action = period_data.get('action', '观望')
                            st.metric("操作建议", action)
                        
                        with col3:
                            risk = period_data.get('risk', '未知')
                            st.metric("风险等级", risk)
                        
                        st.write(f"**分析周期**: {period_data.get('period', '')}")
                        st.write(f"**关注指标**: {period_data.get('focus', '')}")
                        st.write(f"**盈利目标**: {period_data.get('profit_target', '')}")
                        st.write(f"**止损位置**: {period_data.get('stop_loss', '')}")
                        
                        signals = period_data.get('signals', [])
                        if signals:
                            st.markdown("**技术信号**:")
                            for signal in signals:
                                st.write(f"• {signal}")
        
        # ===== 5. 风险收益比 =====
        st.markdown("---")
        st.subheader("⚖️ 风险收益比分析")
        risk_reward = trading_plan.get('risk_reward', {})
        
        if risk_reward:
            col1, col2, col3 = st.columns(3)
            
            with col1:
                profit_percent = risk_reward.get('profit_percent', 0)
                st.metric("潜在收益", f"{profit_percent:.2f}%",
                         delta=f"¥{risk_reward.get('potential_profit', 0):.2f}")
            
            with col2:
                loss_percent = risk_reward.get('loss_percent', 0)
                st.metric("潜在亏损", f"{loss_percent:.2f}%",
                         delta=f"-¥{risk_reward.get('potential_loss', 0):.2f}",
                         delta_color="inverse")
            
            with col3:
                ratio = risk_reward.get('risk_reward_ratio', 0)
                st.metric("风险收益比", f"{ratio:.2f}:1")
            
            evaluation = risk_reward.get('evaluation', '')
            if '优秀' in evaluation:
                st.success(f"✅ {evaluation} - 建议关注")
            elif '良好' in evaluation:
                st.info(f"👍 {evaluation} - 可以考虑")
            elif '一般' in evaluation:
                st.warning(f"⚠️ {evaluation} - 谨慎参与")
            else:
                st.error(f"❌ {evaluation} - 不建议操作")
            
            # 可视化风险收益
            fig = go.Figure()
            
            fig.add_trace(go.Bar(
                x=['潜在收益', '潜在亏损'],
                y=[risk_reward.get('potential_profit', 0), risk_reward.get('potential_loss', 0)],
                marker_color=['#26a69a', '#ef5350'],
                text=[f"+{risk_reward.get('potential_profit', 0):.2f}", 
                      f"-{risk_reward.get('potential_loss', 0):.2f}"],
                textposition='auto',
            ))
            
            fig.update_layout(
                title='风险收益对比',
                yaxis_title='金额 (¥)',
                height=300,
                showlegend=False
            )
            
            st.plotly_chart(fig, use_container_width=True)
            
            # 关键价位
            st.markdown("##### 🎯 关键价位")
            col1, col2, col3 = st.columns(3)
            
            with col1:
                st.metric("当前价", f"¥{risk_reward.get('current_price', 0):.2f}")
            
            with col2:
                st.metric("目标价", f"¥{risk_reward.get('target_price', 0):.2f}", 
                         delta="预期收益位")
            
            with col3:
                st.metric("止损价", f"¥{risk_reward.get('stop_loss', 0):.2f}",
                         delta="风险控制位", delta_color="inverse")
        
        # 生成时间
        generated_at = trading_plan.get('generated_at', '')
        if generated_at:
            st.caption(f"📅 分析生成时间: {generated_at}")
        
    except Exception as e:
        logger.error(f"显示交易决策时出错: {e}\n{traceback.format_exc()}")
        st.error(f"⚠️ 显示交易决策时出现错误，详细信息已记录到日志")

